fix: compress JSON/buffer bodies in beforeResponse (#8, #5)#17
Merged
Conversation
`compress` only handled string bodies, so `/server/api` responses (plain objects) and other non-string bodies were never compressed via the `beforeResponse` hook. - compress string, Buffer/Uint8Array/ArrayBuffer and JSON (object) bodies; objects are serialized and tagged as `application/json` like h3 does, while streams/empty bodies are skipped - document the `beforeResponse` hook for SWR/ISR cached routes and `/server/api` - tests for object bodies on both the h3 v1 app hook and the mutable path Closes #8 Closes #5 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
compress()guarded ontypeof response.body === 'string', so anything that isn't a string was silently left uncompressed. In Nitro'sbeforeResponsehook (the one that also fires for/server/apiand SWR/ISR cached routes), the body is the raw handler return value — for a JSON endpoint that's a plain object, not a string. Result: API/cached responses were never compressed (#8), and there was no documented way to compress cached responses (#5).Changes
compress()now handles non-string bodies:string→ as beforeBuffer/Uint8Array/ArrayBuffer→ compressed as-isapplication/json(mirroring how h3 serializes objects)/server/api" section documenting thebeforeResponsehook approach, with a note on content-type guarding.onBeforeResponse) and the mutable/mockEvent path, for gzip and brotli.Note: the h3 v2
compression()middleware already handled JSON bodies (viatoResponse); this fix targets the v1 / Nitro mutable-response path.Verified locally against both h3 v1 and v2; the CI matrix covers node 18/20 × h3 v1/v2.
Closes #8
Closes #5
🤖 Generated with Claude Code